﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;

namespace NewTools
{
    public partial class MainWindow : Form
    {
        private AutoThread mAutoThread = null;
        private Thread mThread = null;
        private LoadCmdThread mLoadCmdThread = null;
        public  SynchronizationContext mSynchronizationContext = null;
        private DateTime timeNow = new DateTime();
        private TimeSpan timeSpan = new TimeSpan();
        private Utils.RunMode runMode = Utils.RunMode.StopMode;
        private Int32 sDefaultCmdIndex = 0;

        public MainWindow()
        {
            //设定按字体来缩放控件 
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            //设定字体大小为12px      
            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, 
                System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            InitializeComponent();           
        }

        private void Button_Connect_Click(object sender, EventArgs e)
        {
            if (!SerialPortUtil.GetInstance(this).TvSerialPort_Check())
            {
                MessageBox.Show(Properties.Resources.NoteError,Properties.Resources.Error);
                return;
            }
            if (Button_Connect.Text.Equals(Properties.Resources.Connect))
            {
                SerialPortUtil.GetInstance(this).TvSerialPortProperty_Set();
                try
                {
                    SerialPortTv.Open();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
                
                if (SerialPortTv.IsOpen)
                {
                    Button_Connect.Text = Properties.Resources.Disconnect;
                    TvSTatusLabel.Text = Properties.Resources.TvSerialPortConnect;
                    PictureBoxTv.Image = Properties.Resources.link;
                    ControlUtil.GetInstance(this).TvSerialControlEnable_Set(false);
                    SaveValue.GetInstance(this).TvSerialProperty_Save();
                    
                }
                else {

                    Button_Connect.Text = Properties.Resources.Connect;
                    TvSTatusLabel.Text = Properties.Resources.TvSerialPortDisconnect;
                    PictureBoxTv.Image = Properties.Resources.broken_link;
                    ControlUtil.GetInstance(this).TvSerialControlEnable_Set(true);
                }
            }
            else 
            {
                SerialPortTv.Close();
                Button_Connect.Text = Properties.Resources.Connect;
                TvSTatusLabel.Text = Properties.Resources.TvSerialPortDisconnect;
                PictureBoxTv.Image = Properties.Resources.broken_link;
                ControlUtil.GetInstance(this).TvSerialControlEnable_Set(true);
            }
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            mAutoThread = new AutoThread(this, ComboBoxModel.Text);
            SerialPortUtil.GetInstance(this).AvailableSerialPort_Get();
            ControlUtil.GetInstance(this).CurrentTime_Get();
            ControlUtil.GetInstance(this).SignalBoxNumber_Set();
            ControlUtil.GetInstance(this).ModelComboBox_Set();
            // 创建线程，但未启动
            mSynchronizationContext = SynchronizationContext.Current; 
            mLoadCmdThread = new LoadCmdThread(this);
            new Thread(mLoadCmdThread.Run).Start();
        }


        private void SerialPortTv_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            this.Invoke((EventHandler)(delegate 
            {
                try
                {
                    if (runMode == Utils.RunMode.ManualMode)
                    {
                        byte[] receiveData = new byte[SerialPortTv.BytesToRead];
                        SerialPortTv.Read(receiveData, 0, receiveData.Length);
                        String data = null;
                        for (Int32 i = 0; i < receiveData.Length; i++)
                        {
                            data += (receiveData[i].ToString("X2") + " ");
                        }
                        try
                        {
                            string[] dataList = data.Split(' ');
                            if (dataList[0] != "55")
                                return;
                        }
                        catch (Exception ex) 
                        { 
                            Console.WriteLine(ex.ToString());
                        }
                        
                        
                        string functionName = ParseIni.GetInstance().DefaultCommandFunction_Get(this.sDefaultCmdIndex);
                        
                        if (functionName == "")
                        {
                            Manual_Receive_TextBox.AppendText(Properties.Resources.ReveiveFormate + data + "\r\n");
                        }
                        else
                        {
                            string status = CompareResult.GetInstance().RunFunctionSchedule(functionName, data);
                            Manual_Receive_TextBox.AppendText(Properties.Resources.ReveiveFormate + data + "\r\n");
                            Manual_Receive_TextBox.AppendText(" " + ParseIni.GetInstance().DefaultStringCmdNameById_Get(this.sDefaultCmdIndex) + "     " + status + "\r\n");
                        }
                        
                    }
                    else if (runMode == Utils.RunMode.AutoMode) 
                    {
                        byte[] receiveData = new byte[SerialPortTv.BytesToRead];
                        SerialPortTv.Read(receiveData, 0, receiveData.Length);
                        String data = null;
                        for (Int32 i = 0; i < receiveData.Length; i++)
                        {
                            data += (receiveData[i].ToString("X2") + " ");

                        }
                        TextBox_Auto_Receive.AppendText(Properties.Resources.ReveiveFormate + data + "\r\n");

                    }
                }
                catch(Exception){

                    MessageBox.Show(Properties.Resources.SendDataError, Properties.Resources.Error);
                }
            }));

        }

        private void RefreshTimer_Tick(object sender, EventArgs e)
        {
            ControlUtil.GetInstance(this).CurrentTime_Get();
        }

        private void Manual_Send_Button_Click(object sender, EventArgs e)
        {
            runMode = Utils.RunMode.ManualMode;
            if (SerialPortTv.IsOpen)
            {
                byte[] sendData = ParseIni.GetInstance().DefaultCommandById_Get(ComboBox_Command.SelectedIndex);
                SerialPortTv.Write(sendData,0,sendData.Length);
                Manual_Receive_TextBox.AppendText(Properties.Resources.SendFormate + ParseIni.GetInstance().DefaultStringCommandById_Get(ComboBox_Command.SelectedIndex) + "\r\n");
            }
            else {
                MessageBox.Show(Properties.Resources.SerialProtClose,Properties.Resources.Error);
            }
        }

        private void Button_Clear_Manual_Text_Click(object sender, EventArgs e)
        {
            Manual_Receive_TextBox.Clear();
        }

        private void Button_Auto_Start_Click(object sender, EventArgs e)
        {
            TextBox_Auto_Receive.Clear();
            runMode = Utils.RunMode.AutoMode;
            if (Button_Auto_Start.Text.Equals(Properties.Resources.Start))
            {
                Button_Auto_Start.Text = Properties.Resources.End;

                if (mThread == null) {
                    mThread = new Thread(mAutoThread.AutoRun);
                    mThread.Start();
                }
                AutoRunTimer.Start();
                timeNow = DateTime.Now;
                ProgressBarAutoRun.Maximum = ParseIni.GetInstance().AutoRunCommandNumber_Get(ComboBoxModel.Text);
            }
            else 
            {
                Button_Auto_Start.Text = Properties.Resources.Start;
                mAutoThread.exitAutoRunThread();
                mThread = null;
                AutoRunTimer.Stop();
            }
        }

        public void LoadCmdThreadExit(object state)
        {
            ComboBox_Command.Items.AddRange((string [] )state);
            ComboBox_Command.SelectedIndex = 0;
        }
            /**
             * 线程退出的时候 发送的消息
             * 函数的回调
             * 
             */
        public void ThreadExit(object state)
        {
            Console.WriteLine("ThreadExit");
            runMode = Utils.RunMode.StopMode;
            TextBox_Auto_Receive.AppendText(Properties.Resources.AutoRunEnd + "\r\n");
            Button_Auto_Start.Text = Properties.Resources.Start;
            mThread = null;
            AutoRunTimer.Stop();
        }

        /*
         * 自动化执行每条命令后发送的消息
         * 
         */
        public void ExecuteAutoCommand(object state)
        {
            Console.WriteLine("ExecuteAutoCommand    ==    " + state);
            Int32 cmdNum = ParseIni.GetInstance().AutoRunCommandNumber_Get(ComboBoxModel.Text);
            string cmdValue = ParseIni.GetInstance().AutoRunStringCommandById_Get((Int32)state,ComboBoxModel.Text);
            string cmdName = ParseIni.GetInstance().AutoRunStringCommandNameById_Get((Int32)state, ComboBoxModel.Text);
            byte[] sendData = ParseIni.GetInstance().AutoRunCommandById_Get((Int32)state, ComboBoxModel.Text);
            if (SerialPortTv.IsOpen)
                SerialPortTv.Write(sendData, 0, sendData.Length);
            TextBox_Auto_Receive.AppendText(cmdName + "\r\n");
            TextBox_Auto_Receive.AppendText(Properties.Resources.SendFormate + cmdValue + "\r\n");
            ProgressBarAutoRun.Value = (Int32)state + 1;
            LabelProgress.Text = Convert.ToString((Int32)state + 1) + "/" + Convert.ToString(cmdNum);
           
        }

        private void Button_Auto_clear_Click(object sender, EventArgs e)
        {
            TextBox_Auto_Receive.Clear();
        }

        private void AutoRunTimer_Tick(object sender, EventArgs e)
        {
            Console.WriteLine("Label_Auto_time_Click");
            timeSpan = DateTime.Now - timeNow;
            Label_Auto_time.Text = String.Format("{0:00}:{1:00}:{2:00}",timeSpan.Hours,
                timeSpan.Minutes,timeSpan.Seconds);
        }

        private void Button_Signal_Box_Click(object sender, EventArgs e)
        {
            if (ComboBoxSerialSignal.Text.Trim() == "")
            {
                MessageBox.Show(Properties.Resources.NoteError, Properties.Resources.Error);
                return;
            }
            if (Button_Signal_Box.Text.Equals(Properties.Resources.ConnectSignalSerialPort))
            {
                SerialPortSignal.PortName = ComboBoxSerialSignal.Text.Trim();
                SerialPortSignal.BaudRate = 115200;
                SerialPortSignal.DataBits = 8;

                SerialPortSignal.StopBits = StopBits.One;
                SerialPortSignal.Parity = Parity.None;
                try
                {
                    SerialPortSignal.Open();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            
                if (SerialPortSignal.IsOpen)
                {
                    Button_Signal_Box.Text = Properties.Resources.DisconnectSignalSerialPort;
                    PictureBoxSignalBox.Image = Properties.Resources.link;
                    ControlUtil.GetInstance(this).SignalControlEnable_Set(true);
                    SignalStatusLabel.Text = Properties.Resources.signalSerialPortConnect ;
                    ParseIni.GetInstance().SignalSerialPortName_Write(ComboBoxSerialSignal.Text.Trim());
                }
                else 
                {
                    Button_Signal_Box.Text = Properties.Resources.ConnectSignalSerialPort;
                    PictureBoxSignalBox.Image = Properties.Resources.broken_link;
                    SignalStatusLabel.Text = Properties.Resources.signalSerialPortDisconnect ;
                    MessageBox.Show(Properties.Resources.SerialPortOpenFail, Properties.Resources.Error);
                    ControlUtil.GetInstance(this).SignalControlEnable_Set(false);
                }
            }
            else {

                Button_Signal_Box.Text = Properties.Resources.ConnectSignalSerialPort;
                PictureBoxSignalBox.Image = Properties.Resources.broken_link;
                SignalStatusLabel.Text = Properties.Resources.signalSerialPortDisconnect;
                SerialPortSignal.Close();
                ControlUtil.GetInstance(this).SignalControlEnable_Set(false);
            }
        }

        private void ButtonTvRefresh_Click(object sender, EventArgs e)
        {
            SerialPortUtil.GetInstance(this).AvailableSerialPort_Get();
        }

        private void Button_Timming_Click(object sender, EventArgs e)
        {
            string num = NumericUpDownTimming.Value.ToString();
            string cmd = "run tim " + num + ";";
            ParseIni.GetInstance().TimmingNumber_Write(NumericUpDownTimming.Value.ToString());
            if (SerialPortSignal.IsOpen)
            {
                Console.WriteLine(cmd);
                try
                {
                    byte[] sendData =  Encoding.ASCII.GetBytes(cmd);
                    SerialPortSignal.Write(sendData, 0, sendData.Length);
                }
                catch 
                {
                    MessageBox.Show(Properties.Resources.SendDataError,Properties.Resources.Error);
                    return;
                }
            }
            else 
            {
                MessageBox.Show(Properties.Resources.SerialProtClose, Properties.Resources.Error);
            }
        }
        private void Button_Pattern_Click(object sender, EventArgs e)
        {
            string num = NumericUpDownPattern.Value.ToString();
            string cmd = "run ptn " + num + ";";
            ParseIni.GetInstance().PatternNumber_Write(NumericUpDownPattern.Value.ToString());
            if (SerialPortSignal.IsOpen)
            {
                Console.WriteLine(cmd);
                try
                {
                    byte[] sendData = Encoding.ASCII.GetBytes(cmd);
                    SerialPortSignal.Write(sendData, 0, sendData.Length);
                }
                catch
                {
                    MessageBox.Show(Properties.Resources.SendDataError, Properties.Resources.Error);
                    return;
                }
            }
            else
            {
                MessageBox.Show(Properties.Resources.SerialProtClose, Properties.Resources.Error);
            }

        }

        private void ButtonSignalRefresh_Click(object sender, EventArgs e)
        {
            SerialPortUtil.GetInstance(this).AvailableSerialPort_Get();
        }

        private void SerialPortSignal_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            this.Invoke((EventHandler)(delegate
            {
                try
                {           
                    byte[] receiveData = new byte[SerialPortSignal.BytesToRead];
                    SerialPortSignal.Read(receiveData, 0, receiveData.Length);
                    string data = Encoding.ASCII.GetString(receiveData);
                    TextBoxSignalReceive.AppendText(DateTime.Now.ToString("hh:mm:ss") + " " + data);                    
                }
                catch (Exception)
                {
                    MessageBox.Show(Properties.Resources.ReceiveDataError, Properties.Resources.Error);
                }
            }));
        }

        private void Button_WB_Connect_Click(object sender, EventArgs e)
        {
            
        }

        private void ComboBoxModel_SelectedIndexChanged(object sender, EventArgs e)
        {
            ParseIni.GetInstance().ModelName_Write(ComboBoxModel.Text);
            mAutoThread.SetFloderName(ComboBoxModel.Text);
        }

        private void TextBoxSN_TextChanged(object sender, EventArgs e)
        {
            Console.WriteLine("TextBoxSN_TextChanged");
        }

        private void ComboBox_Command_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.sDefaultCmdIndex = ComboBox_Command.SelectedIndex;
        }
    }
}
